package cqie.personal.frame.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import cqie.personal.frame.bo.*;
import cqie.personal.frame.entity.ClassInfo;
import cqie.personal.frame.entity.UserInfo;
import cqie.personal.frame.exception.DataBaseUpdateException;
import cqie.personal.frame.exception.LoginFailException;
import cqie.personal.frame.exception.ValidationFailException;
import cqie.personal.frame.mapper.CharacterInfoMapper;
import cqie.personal.frame.mapper.ClassInfoMapper;
import cqie.personal.frame.mapper.UserInfoMapper;
import cqie.personal.frame.mapper.UserViewMapper;
import cqie.personal.frame.service.UserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cqie.personal.frame.util.JwtUtil;
import cqie.personal.frame.util.MD5Util;
import cqie.personal.frame.util.RegExpValidatorUtils;
import cqie.personal.frame.vo.PageVO;
import cqie.personal.frame.vo.UserView;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Yeeeeee
 * @since 2021-09-01
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private UserViewMapper userViewMapper;
    @Resource
    private CharacterInfoMapper characterInfoMapper;
    @Resource
    private ClassInfoMapper classInfoMapper;

    @Override
    public UserView login(UserLoginBO userLoginBO) throws ValidationFailException, LoginFailException {
        if(userLoginBO == null){
            throw new ValidationFailException("服务器抽风啦，没能获取到参数");
        }
        if(userLoginBO.getUserAccount() == null || userLoginBO.getUserAccount().equals(" ")){
            throw new ValidationFailException("账号不能是空的哦，请先输入要登录的账号吧");
        }
        if(userLoginBO.getUserPassword() == null || userLoginBO.getUserPassword().equals(" ")){
            throw new ValidationFailException("密码不能是空的哦");
        }

        QueryWrapper<UserView> queryWrapper;
        switch (userAccountValid(userLoginBO.getUserAccount())){
            case 1 : {
                queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_phone",userLoginBO.getUserAccount());
                queryWrapper.eq("user_password",MD5Util.getMd5(userLoginBO.getUserPassword()));
            }break;
            case 2 :{
                queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_account",userLoginBO.getUserAccount());
                queryWrapper.eq("user_password", MD5Util.getMd5(userLoginBO.getUserPassword()));
            }break;
            case 3 :{
                queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("uid",userLoginBO.getUserAccount());
                queryWrapper.eq("user_password", MD5Util.getMd5(userLoginBO.getUserPassword()));
            }break;
            default: return null;
        }
        UserView user = userViewMapper.selectOne(queryWrapper);
        if(user == null) {
            throw new LoginFailException("错误的账号密码");
        }
        if(user.getUserAbandon()){
            throw new LoginFailException("账号已停用");
        }
        return user;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean quit(Integer id) {
        if(id == null){
            return false;
        }
        if(id < 0){
            return false;
        }
        UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",id);
        updateWrapper.set("user_token",null);
        return userInfoMapper.update(null,updateWrapper)==1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public synchronized boolean register(UserRegisterBO user) throws ValidationFailException {
        if(user == null){
            throw new ValidationFailException("服务器抽风了，稍后重试一下吧");
        }
        if(user.getUserAccount() == null){
            throw new ValidationFailException("账号不能为空哦");
        }
        if(user.getUserAccount().length()<3||user.getUserAccount().length()>16){
            throw new ValidationFailException("账号长度不对哦");
        }
        if(RegExpValidatorUtils.isNumber(user.getUserAccount())){
            throw new ValidationFailException("账号不支持全数字啦，加些字母吧");
        }
        if(!RegExpValidatorUtils.isAccount(user.getUserAccount())){
            throw new ValidationFailException("账号不支持除'_'以外的特殊字符啦，修改一下吧");
        }
        if(user.getUserName() == null){
            throw new ValidationFailException("ε=(´ο｀*)))唉，不取个好听的昵称吗?");
        }
        if(user.getUserName().length()>20){
            throw new ValidationFailException("昵称太长了，数据库装不下了o(╥﹏╥)o，稍微短点吧");
        }
        if(user.getUserPassword() == null){
            throw new ValidationFailException("密码不能为空哦");
        }
        if(user.getUserPassword().length()<6){
            throw new ValidationFailException("密码太短了，再加长一点吧");
        }
        if(user.getUserPasswordConfirm() == null ){
            throw new ValidationFailException("二次确认密码不能为空哦");
        }
        if(!user.getUserPassword().equals(user.getUserPasswordConfirm())){
            throw new ValidationFailException("两次密码不一样哦,再确认一遍吧");
        }
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("uid");
        queryWrapper.last(" LIMIT 1 ");
        int uid;
        try {
             uid = userInfoMapper.selectOne(queryWrapper).getUid() + 1;
        }catch (Exception e){
            return false;
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setUid(uid);
        userInfo.setUserAccount(user.getUserAccount());
        userInfo.setUserPassword(MD5Util.getMd5(user.getUserPassword()));
        userInfo.setUserAbandon(0);
        userInfo.setUserName(user.getUserName());
        Date date = new Date();
        userInfo.setCreatePerson(uid);
        userInfo.setCreateTime(date);
        userInfo.setLastUpgradePerson(uid);
        userInfo.setLastUpgradeTime(date);

        return userInfoMapper.insert(userInfo) == 1 ;
    }

    @Override
    public boolean accountValid(String userAccount) throws ValidationFailException {
        QueryWrapper<UserInfo> queryWrapper;
        switch (userAccountValid(userAccount)){
            case 1 : {
                queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_phone",userAccount);
            }break;
            case 2 :{
                queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_account",userAccount);
            }break;
            case 3 :{
                queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("uid",userAccount);
            }break;
            default: throw new ValidationFailException("账号格式有误");
        }
        UserInfo user = userInfoMapper.selectOne(queryWrapper);

        return user == null;
    }

    @Override
    public boolean uidValid(Integer uid) {
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid",uid);
        queryWrapper.eq("user_role",0);
        if(userInfoMapper.selectCount(queryWrapper)<1){
            return false;
        }
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid",uid);
        queryWrapper.isNull("student_class_id");

        return userInfoMapper.selectCount(queryWrapper)==1;
    }

    @Override
    public synchronized boolean addStudentIntoClass(AddModifyStudentBO addModifyBO) throws ValidationFailException {
        if(addModifyBO == null){
            throw new ValidationFailException("伺服器錯誤");
        }
        if(addModifyBO.getUid() == null){
            throw new ValidationFailException("student uid can not be none");
        }
        if(!uidValid(addModifyBO.getUid())){
            throw new ValidationFailException("学生不可用");
        }
        if(addModifyBO.getClassId()==null){
            throw new ValidationFailException("error , target can not be none ");
        }
        QueryWrapper<ClassInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",addModifyBO.getClassId());
        if(classInfoMapper.selectCount(queryWrapper)!=1){
            throw new ValidationFailException("error , target not found");
        }
        UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("uid",addModifyBO.getUid());
        updateWrapper.set("student_class_id",addModifyBO.getClassId());

        return userInfoMapper.update(null,updateWrapper)==1;
    }

    @Override
    public synchronized boolean removeStudentFromClass(AddModifyStudentBO addModifyBO) throws ValidationFailException {
        if(addModifyBO == null){
            throw new ValidationFailException("伺服器錯誤");
        }
        if(addModifyBO.getUid() == null){
            throw new ValidationFailException("student uid can not be none");
        }
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid",addModifyBO.getUid());
        UserInfo user = userInfoMapper.selectOne(queryWrapper);
        if(user ==null){
            throw new ValidationFailException("student not found");
        }
        if(addModifyBO.getClassId()==null){
            throw new ValidationFailException("error , target can not be none ");
        }
        QueryWrapper<ClassInfo> classInfoQueryWrapper = new QueryWrapper<>();
        classInfoQueryWrapper.eq("id",addModifyBO.getClassId());
        if(classInfoMapper.selectCount(classInfoQueryWrapper)!=1){
            throw new ValidationFailException("error , target not found");
        }
        UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("uid",addModifyBO.getUid());
        updateWrapper.set("student_class_id",null);

        return userInfoMapper.update(null,updateWrapper)==1;
    }

    @Override
    public PageVO<List<UserView>> getAllUser(GetUserBO user) throws ValidationFailException {
        if(user == null){
            throw new ValidationFailException("服务器抽风啦，稍后刷新页面重试一下吧");
        }
        QueryWrapper<UserView> queryWrapper = new QueryWrapper<>();
        if(user.getClassId()!=null){
            queryWrapper.eq("student_class_id",user.getClassId());
        }
        if(user.getDepartmentId()!=null){
            queryWrapper.eq("teacher_department_id",user.getDepartmentId());
        }
        if(user.getUserName()!=null){
            queryWrapper.likeRight("user_name",user.getUserName());
        }
        if(user.getUserType()!=null){
            queryWrapper.eq("user_role",user.getUserType());
        }
        if(user.getUserAccount()!=null){
            queryWrapper.like("user_account",user.getUserAccount());
        }
        if(user.getUid()!=null){
            queryWrapper.likeRight("uid",user.getUid());
        }
        if(user.getUserPhone()!=null){
            queryWrapper.eq("user_phone",user.getUserPhone());
        }
        if(user.getCharacterId()!=null){
            if(user.getCharacterId()<0){
                throw new ValidationFailException("没有这种角色啦，重新选一个吧");
            }else {
                queryWrapper.in("character_id",user.getCharacterId());
            }
        }
        if(user.getCharacterName()!=null){
            queryWrapper.like("character_name",user.getCharacterName());
        }
        if(user.getUserAbandon()!=null){
            queryWrapper.eq("user_abandon",user.getUserAbandon());
        }
        if(user.getUserSex()!=null){
            if(user.getUserSex()!=-1) {
                queryWrapper.eq("user_sex", user.getUserSex());
            }
        }
        if(user.getUserId()!=null){
            queryWrapper.eq("id",user.getUserId());
        }

        queryWrapper.last(" LIMIT "+user.getPageOff()+" , " + user.getPageMax());
        List<UserView> userInfoList = userViewMapper.selectList(queryWrapper);
        PageVO<List<UserView>> result = new PageVO<>(userInfoList);
        result.setPageNo(user.getPageNo());
        result.setPageSize(user.getPageMax());
        result.setRecordCount(userInfoList.size());
        Integer totalCount = userViewMapper.selectCount(queryWrapper);
        if(totalCount == null){
            result.setTotalCount(0);
            result.setTotalPage(0);
        }else {
            result.setTotalCount(totalCount);
            result.setTotalPage(result.getTotalCount() % result.getPageSize() == 0 ?
                    result.getTotalCount() / result.getPageSize() :
                    result.getTotalCount() / result.getPageSize() + 1);
        }
        return result;
    }

    private int userAccountValid(String account) throws ValidationFailException {

        if(account.length()<3 || account.length()>16){
            System.out.println(account);
            throw new ValidationFailException("账号格式不正确哦，请检查一下吧");
        }
        //是否为全数字（1，是手机号登录(11位全数字) ; 2,UID(9位全数字) ; 3 ，非法账号）
        if(RegExpValidatorUtils.isNumber(account)){
            //是否为手机号
            if(RegExpValidatorUtils.isTelephone(account)){
                return 1;
            }
            if(account.length()==9){
                return 3;
            }
            //是非法账号
            throw new ValidationFailException("账号格式不正确哦，请检查一下吧");
        }
        //是普通账号（非全数字的5-16位任意字符）
        if(RegExpValidatorUtils.isAccount(account)){
            return 2;
        }
        throw new ValidationFailException("账号格式不正确哦，请检查一下吧");
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public String updateToken(Integer uid, Integer id){
        String token = JwtUtil.InsertToken(uid,id);
        UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",id);
        updateWrapper.set("user_token",token);
        if (userInfoMapper.update(null,updateWrapper)<0){
           return null;
        }
        return token;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public boolean addUser(AddModifyUserBO userBO) throws ValidationFailException, DataBaseUpdateException {
        if(userBO==null){
            throw new ValidationFailException("服务器抽风啦，稍后刷新页面重试一下吧");
        }
        if(userBO.getUserAccount()==null){
            throw new ValidationFailException("账号是登录的凭证哦，不能为空啦");
        }
        if(userBO.getUserAccount().length()<3||userBO.getUserAccount().length()>16){
            throw new ValidationFailException("账号长度不对哦");
        }
        if(RegExpValidatorUtils.isNumber(userBO.getUserAccount())){
            throw new ValidationFailException("账号不支持全数字啦，加些字母吧");
        }
        if(!RegExpValidatorUtils.isAccount(userBO.getUserAccount())){
            throw new ValidationFailException("账号不支持除'_'以外的特殊字符啦，修改一下吧");
        }
        if(userBO.getUserName() == null){
            throw new ValidationFailException("ε=(´ο｀*)))唉，不取个好听的昵称吗?");
        }
        if(userBO.getUserName().length()>20){
            throw new ValidationFailException("昵称太长了，数据库装不下了o(╥﹏╥)o，稍微短点吧");
        }
        if(userBO.getUserPassword() == null){
            throw new ValidationFailException("密码不能为空哦");
        }
        if(userBO.getUserPassword().length()<6){
            throw new ValidationFailException("密码太短了，再加长一点吧");
        }
        userAccountValid(userBO.getUserAccount());
        if(userBO.getUserPassword()==null) {
            throw new ValidationFailException("密码是重要的登录凭证，可不能为空");
        }
        if(!this.accountValid(userBO.getUserAccount())){
            throw new ValidationFailException("都说了账号不可用了");
        }
        if(userBO.getUserRole()>1){
           throw new ValidationFailException("没有新建管理员的权限");
        }
        UserInfo user = new UserInfo();
        user.setUserRole(userBO.getUserRole());
        user.setUserAccount(userBO.getUserAccount());
        user.setUserPassword(MD5Util.getMd5(userBO.getUserPassword()));
        user.setUserName(userBO.getUserName());
        if(userBO.getUserAbandon()!=null){
            if(userBO.getUserAbandon())
                user.setUserAbandon(1);
        }
        if(userBO.getUserSex()!=null){
            user.setUserSex(userBO.getUserSex());
        }
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("uid");
        queryWrapper.last(" LIMIT 1 ");
        int uid;
        try {
            uid = userInfoMapper.selectOne(queryWrapper).getUid() + 1;
        }catch (Exception e){
            return false;
        }
        user.setUid(uid);
        Date date = new Date();
        user.setCreateTime(date);
        user.setCreatePerson(userBO.getUid());
        user.setLastUpgradePerson(userBO.getUid());
        user.setLastUpgradeTime(date);
        if(userInfoMapper.insert(user)!=1){
            throw new DataBaseUpdateException("更新数据库失败");
        }
        System.out.println(userBO.getCharacterId());
        if(userBO.getCharacterId()!=null&&userBO.getCharacterId().size()>0){
            for (int id : userBO.getCharacterId()){
                if(characterInfoMapper.InsertUserCharacter(uid,id)!=1){
                    throw new DataBaseUpdateException("数据库更新失败");
                }
            }
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public boolean modifyUser(AddModifyUserBO userBO) throws ValidationFailException, DataBaseUpdateException {
        if(userBO==null) {
            throw new ValidationFailException("服务器抽风啦，稍后刷新页面重试一下吧");
        }
        if(userBO.getId()==null){
            throw new ValidationFailException("服务器被玩坏了，找不到指定对象了，刷新重试一下吧");
        }
        QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
        userInfoQueryWrapper.eq("id",userBO.getId());
        UserInfo user =  userInfoMapper.selectOne(userInfoQueryWrapper);
        if(user ==null){
            throw new ValidationFailException("唉？！ 找不到对应的用户啦，重新选一个吧");
        }
        if(userBO.getUserName()==null){
            throw new ValidationFailException("名字不能改为空白啦");
        }
        if(userBO.getUserName().length()>20){
            throw new ValidationFailException("昵称太长了，数据库装不下了o(╥﹏╥)o，稍微短点吧");
        }
//        if(userBO.getUserRole()>1){
//            throw new ValidationFailException("不能修改成管理员");
//        }
        user.setUserRole(userBO.getUserRole());
        user.setUserSex(userBO.getUserSex());
        user.setUserName(userBO.getUserName());
        if(userBO.getUserPhone()!=null){
            if(!RegExpValidatorUtils.isTelephone(userBO.getUserPhone())){
                QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.ne("id",userBO.getId());
                queryWrapper.eq("user_phone",userBO.getUserPhone());
                if(userInfoMapper.selectCount(queryWrapper)>0){
                    throw new ValidationFailException("手机号已经被使用了，换一个吧");
                }
                user.setUserPhone(userBO.getUserPhone());
            }else {
                throw new ValidationFailException("手机号格式不对啦");
            }
        }
        if(userBO.getUserAbandon()!=null){
            user.setUserAbandon(userBO.getUserAbandon()?1:0);
        }
        user.setLastUpgradeTime(new Date());
        user.setLastUpgradePerson(userBO.getUid());
        if(userInfoMapper.update(user,userInfoQueryWrapper)!=1){
            throw new DataBaseUpdateException("更新失败了");
        }
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",userBO.getId());
        UserInfo targetUser = userInfoMapper.selectOne(queryWrapper);
        characterInfoMapper.delOldCharacter(targetUser.getUid());
        if(userBO.getCharacterId()!=null&&userBO.getCharacterId().size()>0){
            for (int id : userBO.getCharacterId()){
                if(characterInfoMapper.InsertUserCharacter(targetUser.getUid(),id)!=1){
                    throw new DataBaseUpdateException("数据库更新失败");
                }
            }
        }
        return true;
    }

    @Override
    public Integer getUserPermission(Integer uid) {
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid",uid);
        UserInfo user = userInfoMapper.selectOne(queryWrapper);
        if(user == null){
            return null;
        }
        return user.getUserRole();
    }

}
